#ifndef _GM3D_H
#define _GM3D_H

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "map"
#include "algorithm"
#include "ctime"
#include "omp.h"
#include "random"

// add gctl head files here
#include "gctl/core.h"
#include "gctl/geometry.h"
#include "gctl/utility.h"

using namespace std;

// define error code here
#define GM3D_INVALID_MESH_PARAMETER "Invalid mesh parameter."
#define GM3D_MODEL_INIT_FAIL "Fail to read models' parameter."
#define GM3D_FORWARD_MODEL_INITIALIZED "Forward model initialized from file."
#define GM3D_INVALID_OBS_PARAMETER "Invalid observation parameter."
#define GM3D_NOMODEL_ADDED "No model changed."
#define GM3D_INVALID_MODEL_TYPE "Wrong parameter for model's type."
#define GM3D_INVALID_MODEL_PARAMETER "Invalid model parameter."
#define GM3D_INVALID_MODEL_VAL_TYPE "Wrong parameter for model's value type."

//数据结构
typedef map<int,int> int2intMap; ///< 整型到整形的映射

//模型块体参数
struct modelist
{
	std::string mod_type;
	std::string val_type;
	std::string mod_para;
	double mod_value;
};
typedef vector<modelist> modelistVector;
//直角坐标系顶点 比坐标点位只多一个序号
struct vertex : public gctl::point3dc
{
	int id = -1;
};
typedef vector<vertex> vertexVector;
typedef map<string, vertex> str2vertMap;
//观测点
struct obspoint : public vertex
{
	double val = GCTL_BDL_MAX; double dev = GCTL_BDL_MAX;
};
typedef vector<obspoint> obspointVector;
//块体
struct cube
{
	vertex cen;
	int ids[8] = {-1,-1,-1,-1,-1,-1,-1,-1};
	double dx = GCTL_BDL_MAX; double dy = GCTL_BDL_MAX; double dz = GCTL_BDL_MAX;
};
typedef vector<cube> cubeVector;

class GM3D{
public:
	GM3D(){}
	~GM3D(){}
	void BuildRegularGrid(std::string modspace_para); //初始化反演模型空间
	void AddModels(std::string modentity_file); //读取模型块体参数文件
	void AddRegularBlock(modelist); //添加普通模型块体
	void AddTiltedBlock(modelist); //添加倾斜模型块体
	void AddSphereBlock(modelist); //添加球体椭球体块体
	void AddInterfaceBlock(modelist); //添加密度界面
	//模型操作
	int ReadModel(const char*,const char*);
	//输出模型
	int RegisteredOuput(bool); //注册输出的块体模型
	int OutMshFile(const char*,string); //输出模型文件
	int OutNeighborFile(const char*,const char*); //输出模型块体或顶点的相邻关系 暂缓
	//观测数据
	int InitObs(const char*);
	int OutObs(const char*);
	//正演函数
	int ForwardVz(const char*);
	int ForwardVzx(const char*);
	int ForwardVzy(const char*);
	int ForwardVzz(const char*);
	int ForwardDeltaT(const char*,const char*);
	int ForwardDeltaTx(const char*,const char*);
	int ForwardDeltaTy(const char*,const char*);
	int ForwardDeltaTz(const char*,const char*);
	int ForwardHax(const char*,const char*);
	int ForwardHay(const char*,const char*);
	int ForwardZa(const char*,const char*);
	//返回一个cpoint的位置id
	string point_id(vertex);
public:
	char model_id_[1024];
private:
	int obs_num_, model_num_, vert_num_;
	//正演数组
	obspointVector obs_p_;
	gctl::_2d_vector input_models_;
	gctl::_1s_vector input_model_names_;
	gctl::_1d_vector forward_model_;
	//模型数据
	cubeVector model_cube_;
	vertexVector model_vert_;
	gctl::_1d_vector model_block_val_;
	modelistVector model_list_;
	gctl::_1i_vector out_ele_ids_;
	gctl::_1i_vector out_ele_data_ids_;
	gctl::_1i_vector out_vert_ids_;
	int2intMap vert_out_map_;
	int2intMap ele_data_out_map_;

	gctl::_2i_vector model_vert_neighbor_; //暂缓
	gctl::_2i_vector model_cube_neighbor_; //暂缓
};
#endif